#include <iostream>
#include <string>

#include "evidenz.hh"

using namespace evz;

typedef float Mass;

typedef int Event;

typedef std::list<std::string> List;

typedef Config<std::string> ConfigurationT;

typedef ConfigSet<std::string> ConfigurationSetT;

typedef Var<std::string> VarT;

typedef VarFactory<std::string> VarFactoryT;

typedef VarSet<std::string> VarDomainT;

typedef Potential<std::string, Event> PotentialT;

struct Player : public MassFunc<Event>
{
  Player(float value) : value_(value)
  {}

  float operator()(Event e) const
  {
    return value_;
  }

private:
  float value_;
};


/*int main()
{
  Event e = 1;

  VarFactory<std::string> vf;
   
  VarT& attack = vf.new_var();
  VarT& gravidade = vf.new_var(); 
    
  attack.add_reals((VarT::start(), "TCP SYN", "Smurf", "TCP FYN", "DNS Hijacking"));//, "BGP Null Route", "WormBlaster", "Orkut"));
  gravidade.add_reals((VarT::start(), "0", "1", "2", "3"));//, "4", "5", "6"));
    
  VarDomainT vs1(vf, (VarDomainT::start(), &attack, &gravidade));
  ConfigurationSetT cs1(vs1);
  cs1.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs1, (ConfigurationT::start(), "TCP FYN", "Low Level"))));
  ConfigurationSetT cs1_all(vs1);
  cs1_all.add_all_configs();
  Player p1(0.8);
  PotentialT player1(vs1);
  player1.add(cs1, p1);
  player1.add(cs1_all, *new MassComplement<Event>(p1));
  player1.check(e);
  
  VarDomainT vs2(vf, (VarDomainT::start(), &attack));
  ConfigurationSetT cs2(vs2);
  cs2.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs2, (ConfigurationT::start(), "DNS Hijacking"))));
  ConfigurationSetT cs2_all(vs2);
  cs2_all.add_all_configs();
  Player p2(0.54);
  PotentialT player2(vs2);
  player2.add(cs2, p2);
  player2.add(cs2_all, *new MassComplement<Event>(p2));
  player2.check(e);
  
  VarDomainT vs3(vf, (VarDomainT::start(), &attack));
  ConfigurationSetT cs3(vs3);
  cs3.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs3, (ConfigurationT::start(), "TCP FYN", "High Level"))));
  ConfigurationSetT cs3_all(vs3);
  cs3_all.add_all_configs();
  Player p3(0.9);
  PotentialT player3(vs3);
  player3.add(cs3, p3);
  player3.add(cs3_all, *new MassComplement<Event>(p3));
  player3.check(e);
  
  VarDomainT vs4(vf, (VarDomainT::start(), &gravidade));
  ConfigurationSetT cs4(vs4);
  cs4.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs4, (ConfigurationT::start(), "Middle Level"))));
  ConfigurationSetT cs4_all(vs4);
  cs4_all.add_all_configs();
  Player p4(0.3);
  PotentialT player4(vs4);
  player4.add(cs4, p4);
  player4.add(cs4_all, *new MassComplement<Event>(p4));
  player4.check(e);
  
  VarDomainT vs5(vf, (VarDomainT::start(), &attack, &gravidade));
  ConfigurationSetT cs5(vs5);
  cs5.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs5, (ConfigurationT::start(), "DNS Hijacking", "High Level"))));
  ConfigurationSetT cs5_all(vs5);
  cs5_all.add_all_configs();
  Player p5(0.3);
  PotentialT player5(vs5);
  player5.add(cs5, p5);
  player5.add(cs5_all, *new MassComplement<Event>(p5));
  player5.check(e);
  
  VarDomainT global_vs(vf, (VarDomainT::start(), &attack, &gravidade));

  ConfigurationSetT csfinal(global_vs);
  ConfigurationT conffinal(global_vs, (ConfigurationT::start(), "TCP FYN", "High Level"));
  csfinal.add_config(conffinal);
 
  PotentialT final = player1.get_comb(player2).get_comb(player3).get_comb(player4).get_comb(player5);
  final.check(e);

  std::cout << "bel = " << final.bel(csfinal, e) << std::endl
 	    << "pls = " << final.pls(csfinal, e) << std::endl
 	    << "dou = " << final.dou(csfinal, e) << std::endl
 	    << "com = " << final.com(csfinal, e) << std::endl
 	    << "ign = " << final.ign(csfinal, e) << std::endl
	    << std::endl;
    
  	return 0;
}*/

int main() {

Event e = 1;

  VarFactory<std::string> vf;
   
  VarT& attack = vf.new_var(); 
  VarT& level = vf.new_var();
  VarT& location = vf.new_var();  
  
  attack.add_reals((VarT::start(), "TCP SYN", "Smurf", "TCP FYN"));
  level.add_reals((VarT::start(), "Low Level", "Middle Level", "High Level"));
  location.add_reals((VarT::start(), "Source End", "Intermediate End", "Victim End"));
  
  //

  VarDomainT global_vs(vf, (VarDomainT::start(), &attack, &level, &location));

  VarDomainT vs1(vf, (VarDomainT::start(), &attack, &level, &location));
  ConfigurationSetT cs1(vs1);
  cs1.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs1, (ConfigurationT::start(), "TCP SYN", "High Level", "Victim End"))));
  ConfigurationSetT cs1_all(vs1);
  cs1_all.add_all_configs();
  Player p1(0.8);
  PotentialT player1(vs1);
  player1.add(cs1, p1);
  player1.add(cs1_all, *new MassComplement<Event>(p1));
  player1.check(e);

  VarDomainT vs2(vf, (VarDomainT::start(), &attack, &level, &location));
  ConfigurationSetT cs2(vs2);
  cs2.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs2, (ConfigurationT::start(), "TCP FYN", "Low Level", "Victim End"))));
  ConfigurationSetT cs2_all(vs2);
  cs2_all.add_all_configs();
  Player p2(0.6);
  PotentialT player2(vs2);
  player2.add(cs2, p2);
  player2.add(cs2_all, *new MassComplement<Event>(p2));
  player2.check(e);
  
  /*VarDomainT vs3(vf, (VarDomainT::start(), &attack, &level, &location));
  ConfigurationSetT cs3(vs3);
  cs3.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs3, (ConfigurationT::start(), "Smurf", "High Level","Victim End" ))));
  ConfigurationSetT cs3_all(vs3);
  cs3_all.add_all_configs();
  Player p3(0.9);
  PotentialT player3(vs3);
  player3.add(cs3, p3);
  player3.add(cs3_all, *new MassComplement<Event>(p3));
  player3.check(e);*/
  
  VarDomainT vs4(vf, (VarDomainT::start(), &attack, &level));
  ConfigurationSetT cs4(vs4);
  cs4.add_configs((ConfigurationSetT::start(), 
		   ConfigurationT(vs4, (ConfigurationT::start(), "TCP SYN", "High Level"))));
  ConfigurationSetT cs4_all(vs4);
  cs4_all.add_all_configs();
  Player p4(0.3);
  PotentialT player4(vs4);
  player4.add(cs4, p4);
  player4.add(cs4_all, *new MassComplement<Event>(p4));
  player4.check(e);
  
  VarDomainT vs5(vf, (VarDomainT::start(), &attack, &level, &location));
  ConfigurationSetT cs5(vs5);
  cs5.add_configs((ConfigurationSetT::start(), 
  ConfigurationT(vs5, (ConfigurationT::start(), "Smurf", "Low Level", "Victim End"))));
  ConfigurationSetT cs5_all(vs5);
  cs5_all.add_all_configs();
  Player p5(0.5);
  PotentialT player5(vs5);
  player5.add(cs5, p5);
  player5.add(cs5_all, *new MassComplement<Event>(p5));
  player5.check(e);

  
  VarDomainT vs6(vf, (VarDomainT::start(), &attack, &level, &location));
  ConfigurationSetT cs6(vs6);
  cs6.add_configs((ConfigurationSetT::start(), 
  ConfigurationT(vs6, (ConfigurationT::start(), "TCP FYN", "Low Level", "Victim End"))));
  ConfigurationSetT cs6_all(vs6);
  cs6_all.add_all_configs();
  Player p6(0.1);
  PotentialT player6(vs6);
  player6.add(cs6, p6);
  player6.add(cs6_all, *new MassComplement<Event>(p6));
  player6.check(e);


  ConfigurationSetT csfinal(global_vs);
  ConfigurationT conffinal(global_vs, (ConfigurationT::start(), "Smurf", "High Level", "Victim End"));
  csfinal.add_config(conffinal);
 

  PotentialT final = player1.get_comb(player2);
  final = final.get_comb(player4);
  final = final.get_comb(player5);
  final = final.get_comb(player6);
  
  final.check(e);

  std::cout << "player1 + player2rob = 0.8075" << final << std::endl;
  std::cout << "Config set " << csfinal 
	    << " and event " << e
	    << " gives" << std::endl
	    << "bel = " << final.bel(csfinal, e) << std::endl
 	    << "pls = " << final.pls(csfinal, e) << std::endl
 	    << "dou = " << final.dou(csfinal, e) << std::endl
 	    << "com = " << final.com(csfinal, e) << std::endl
 	    << "ign = " << final.ign(csfinal, e) << std::endl
	    << "prob = " << final.prob(conffinal, e) << std::endl
	    << "prob = " << final.prob(csfinal, e) << std::endl
	    << std::endl;
    
  	return 0;
}


